package com.hncj.yqfk.service.impl;

import com.hncj.yqfk.dao.CRDJ_Dao;
import com.hncj.yqfk.dao.CRXXLS_Dao;
import com.hncj.yqfk.dao.CRXX_Dao;
import com.hncj.yqfk.ldao.LY_Dao;
import com.hncj.yqfk.entity.*;
import com.hncj.yqfk.service.RygjService;
import com.hncj.yqfk.utils.JsonResult;
import com.hncj.yqfk.utils.MixInfo;
import com.hncj.yqfk.utils.NameConvert;
import com.hncj.yqfk.utils.TimeUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class RygjServiceImpl implements RygjService {
    @Autowired
    CRDJ_Dao crdjDao;

    @Autowired
    CRXX_Dao crxxDao;

    @Autowired
    CRXXLS_Dao crxxlsDao;

    @Autowired
    LY_Dao lyDao;

    @Override
    public JsonResult GetRank() {
        //得到数据
        List<Map<String, Integer>> listmap = crdjDao.GetOrder(TimeUtils.getday());
        //判断是否为空
        if (!listmap.isEmpty()) {
            //创建返回集合
            Map<String, Object> res = new HashMap<>();
            //创建楼宇名称和人数的集合
            ArrayList<String> stringlist = new ArrayList<String>();
            ArrayList<Integer> integerlist = new ArrayList<Integer>();
            //对数据去重累加并使用循环传入数据
            for (Map map : listmap) {
                String mc = map.get("LYMC").toString().replaceAll("号", "").replaceAll("[^\\u4e00-\\u9fa5]", "");
                if (mc.contains("楼")){
                    String[] mcarray =mc.split("楼");
                    mc = mcarray[0].toString()+"楼";
                }
                if (stringlist.contains(mc)) {
                    Integer index = stringlist.indexOf(mc);
                    integerlist.set(index, integerlist.get(index) + Integer.parseInt(map.get("NUM").toString()));
                } else {
                    stringlist.add(mc);
                    integerlist.add(Integer.parseInt(map.get("NUM").toString()));
                }
            }
            Map<String, Integer> hashmap = new HashMap<>();
            for (int i = 0; i < integerlist.size(); i++) {
                hashmap.put(stringlist.get(i), integerlist.get(i));
            }
            //对数据进行排序
            Map treemap = new TreeMap(hashmap);
            //对value进行排序
            //将map.entrySet()转换为list集合
            List<Map.Entry<String, Integer>> list = new ArrayList<>(treemap.entrySet());
            Collections.sort(list, new Comparator<Map.Entry<String, Integer>>() {
                @Override
                public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {
                    return o1.getValue().compareTo(o2.getValue());
                }
            });
            //清理集合
            stringlist.clear();
            integerlist.clear();
            for (Map.Entry<String, Integer> entry : list) {
                stringlist.add(entry.getKey());
                integerlist.add(entry.getValue());
            }
            //将数据传入集合
            Collections.reverse(stringlist);
            Collections.reverse(integerlist);
            res.put("csname", stringlist);
            res.put("rll", integerlist);
            //返回数据
            return JsonResult.custom(200, "", new Date(), res);
        } else {
            //返回数据
            return JsonResult.custom(202, "The server encountered an internal error", new Date(), "");
        }
    }

    @Override
    public Double GetRndByMc(String LYMC) {
        //查询目前容纳度进行判断并返回
        Double value = crdjDao.GetRndByLybh(LYMC + "%", TimeUtils.getday());
        if (value == null) {
            return 0.00;
        } else {
            Double value1s = Double.valueOf(String.format("%.2f", value ));
            return Math.abs(value1s);
        }
    }

    @Override
    public Integer GetHourRndByMc(String LYMC) {
        //查询当前楼宇小时的人流量进行判断并返回
        Integer value = crdjDao.GetHourRndByLybh(LYMC + "%", TimeUtils.getinittime());
        if (value == null) {
            return 0;
        } else {
            return value;
        }
    }

    @Override
    public Integer GetHourRndByDa(String LYMC) {
        //查询当前楼宇小时的学生人流量进行判断并返回
        Integer value = crxxDao.GetByRndDa(NameConvert.getrrightname(LYMC), TimeUtils.getinittime1());
        if (value == null) {
            return 0;
        } else {
            return value;
        }
    }

    @Override
    public Integer GetHourRndByDaLs(String LYMC) {
        //查询当前楼宇小时的教职工人流量进行判断并返回
        Integer value = crxxlsDao.GetByRndDa(NameConvert.getrrightname(LYMC), TimeUtils.getinittime1());
        if (value == null) {
            return 0;
        } else {
            return value;
        }
    }

    @Override
    public JsonResult GetInfoByBhAndDayAndType(String lymc, String stime, String etime, String stype) {
        //当stype为0时查询所有类型
        if ("0".equals(stype)) {
            stype = "%";
        }
        //得到数据
        Map res = GetAllByMC(lymc);
        //查询当天的人流量
        List<Map<String, Object>> listmap = crdjDao.GetByDay(lymc + "%", TimeUtils.getinitday(), TimeUtils.getformattime(), stype);
        //根据提供的时间查询指定人流量
        List<Map<String, Object>> listmap1 = crdjDao.GetByDay(lymc + "%", stime, etime, stype);
        //判断是否为空
        if (!res.isEmpty()) {
            //创建一个用于计算当天人流量的集合
            List<Integer> values = new ArrayList<>();
            //创建接受集合和返回集合
            List<String> date = new ArrayList<>();
            List<Integer> value = new ArrayList<>();
            //使用循环接受数据
            if (!listmap.isEmpty()) {
                for (Map map : listmap) {
                    values.add(Integer.parseInt(map.get("HOUR_JNUM").toString()));
                }
                //今天小时最大人流量
                res.put("rll_max", Collections.max(values));
                //今天的人流量
                res.put("rll_all", values.stream().reduce(Integer::sum).orElse(0));
            } else {
                //今天小时最大人流量
                res.put("rll_max", 0);
                //今天的人流量
                res.put("rll_all", 0);
            }

            for (Map map : listmap1) {
                date.add(map.get("HOUR").toString());
                value.add(Integer.parseInt(map.get("HOUR_JNUM").toString()));
            }
            //当前小时人流量
            res.put("rll", GetHourRndByMc(lymc));
            //楼宇容纳度
            res.put("rnd", GetRndByMc(lymc));
            //时间坐标
            res.put("date", date);
            //小时人流量
            res.put("value", value);
            //返回数据
            return JsonResult.custom(200, "", new Date(), res);
        } else {
            //返回数据
            return JsonResult.custom(202, "The server encountered an internal error", new Date(), "");
        }
    }

    @Override
    public JsonResult GetSchoolRndByDayAndType(String stime, String etime, String stype) {
        //当stype为0时查询所有类型
        if ("0".equals(stype)) {
            stype = "%";
        }
        //得到数据
        List<Map<String, Object>> listmap = crdjDao.GetByDay("%", stime, etime, stype);
        //判断是否为空
        if (!listmap.isEmpty()) {
            //创建接受集合和返回集合
            List<String> dates = new ArrayList<>();
            List<Integer> values = new ArrayList<>();
            Map res = new HashMap();
            //使用循环接受数据
            for (Map map : listmap) {
                dates.add(map.get("HOUR").toString());
                values.add(Integer.parseInt(map.get("HOUR_JNUM").toString()));
            }
            //时间坐标
            res.put("date", dates);
            //小时人流量
            res.put("value", values);
            //返回数据
            return JsonResult.custom(200, "", new Date(), res);
        } else {
            //返回数据
            return JsonResult.custom(202, "The server encountered an internal error", new Date(), "");
        }
    }

    @Override
    public Map<String, Object> GetByDayAndUsername(String USERNAME, String stime, String etime) {
        Map<String, Object> map = new HashMap<>();
        //查询所有坐标，用于返回坐标
        List<LY> lys = lyDao.findAll();
        //通过唯一标识和时间段查询所有信息
        List<CRDJ> list1 = crdjDao.GetByDayAndUsername(USERNAME, stime, etime);
        List<CRXX> list2 = crxxDao.GetByDayAndUsername(USERNAME, stime, etime);
        List<CRXXLS> list3 = crxxlsDao.GetByDayAndUsername(USERNAME, stime, etime);
        //建立一个总表
        List<FHCRXX> list = new ArrayList<>();
        for (CRDJ c : list1) {
            list.add(new FHCRXX(c.getCRSJ(), c.getJCBZ(), c.getLYMC(), c.getFJMC()));
        }
        for (CRXX c : list2) {
            list.add(new FHCRXX(c.getSBSJ(), c.getCRBZ(), c.getCRWZ(), null));
            if (c.getXQ().equals("5")){
                list.add(new FHCRXX(c.getSBSJ(), c.getCRBZ(), "行政楼", null));
            }
        }
        for (CRXXLS c : list3) {
            list.add(new FHCRXX(c.getSBSJ(), c.getCRBZ(), c.getCRWZ(), null));
            if (c.getXQ().equals("5")){
                list.add(new FHCRXX(c.getSBSJ(), c.getCRBZ(), "行政楼", null));
            }
        }
        //对list进行排序
        Collections.sort(list, new Comparator<FHCRXX>() {
            public int compare(FHCRXX o1, FHCRXX o2) {
                return o1.getDate().compareTo(o2.getDate());
            }
        });
        //提取无重复位置坐标
        List<Point> pointList = new ArrayList<>();
        for (int i = 0; i < list.size(); i++) {
            //格式化楼宇名称，与数据可匹配
            if (list.get(i).getWz1().equals("1") || list.get(i).getWz1().equals("2") || list.get(i).getWz1().equals("3") || list.get(i).getWz1().equals("0")) {
                if (list.get(i).getWz1().equals("1")) {
                    list.get(i).setWz1("河南城建学院南门");
                }
                if (list.get(i).getWz1().equals("2")) {
                    list.get(i).setWz1("河南城建学院西门");
                }
                if (list.get(i).getWz1().equals("3")) {
                    list.get(i).setWz1("河南城建学院北门");
                }
                if (list.get(i).getWz1().equals("0")) {
                    list.get(i).setWz1("文管学区东门");
                }


            }
//            else {
//                list.get(i).setWz1(list.get(i).getWz1().replaceAll("[^\\u4e00-\\u9fa5]", ""));
//            }

            //获取楼宇位置坐标
            for (LY ly : lys) {
                if (list.get(i).getWz1().equals(ly.getLYMC())) {
                    pointList.add(new Point(ly.getLYJD(), ly.getLYWD()));
                }
            }
        }

        if(list.isEmpty()){
            map.put("code",202);
        }else {
            map.put("code",200);
            if (list1.isEmpty()){
                if (list2.isEmpty()){
                    map.put("num", list3.get(0).getXH());
                    map.put("name", list3.get(0).getXM());
                }else {
                    map.put("num", list2.get(0).getXH());
                    map.put("name", list2.get(0).getXM());
                }

            }else {
                map.put("num", list1.get(0).getUSERNAME());
                map.put("name", list1.get(0).getCRDJRXM());
            }
            map.put("jccs", list);
            map.put("cszb", pointList);
        }

        return map;
    }

    @Override
    public JsonResult GetInfoByNaDaTy(String lymc, String stime, String etime, String stype) {
        if ("1".equals(stype)) { //学生
            //得到数据
            Map res = GetAllByMC(lymc);
            if (!res.isEmpty()) {
                //查询当天的人流量
                List<Map<String, Object>> listmap = crxxDao.GetByNaDa(NameConvert.getrrightname(lymc), TimeUtils.getinitday(), TimeUtils.getformattime());
                //查询指定时间段，指定大门的单位人流量
                List<Map<String, Object>> listmap1 = crxxDao.GetByNaDa(NameConvert.getrrightname(lymc), stime, etime);
                //创建接受集合和返回集合
                List<String> date = new ArrayList<>();
                List<Integer> value = new ArrayList<>();
                //创建一个用于计算当天人流量的集合
                List<Integer> values = new ArrayList<>();
                //使用循环接收数据
                if (!listmap.isEmpty()){
                    for (Map map:listmap){
                        values.add(Integer.parseInt(map.get("HOUR_JNUM").toString()));
                    }
                    //当天小时最大人流量
                    res.put("rll_max", Collections.max(values));
                    //当天人流量
                    res.put("rll_all", values.stream().reduce(Integer::sum).orElse(0));
                }else{
                    //当天小时最大人流量
                    res.put("rll_max", 0);
                    //当天人流量
                    res.put("rll_all", 0);
                }

                //使用循环查询数据
                for (Map map : listmap1) {
                    date.add(map.get("HOUR").toString());
                    value.add(Integer.parseInt(map.get("HOUR_JNUM").toString()));
                }
                //时间坐标
                res.put("date", date);
                //小时人流量
                res.put("value", value);
                //当前小时人流量
                res.put("rll", GetHourRndByDa(lymc));
                //楼宇容纳度
                res.put("rnd", "0.00");
                //返回数据
                return JsonResult.custom(200, "", new Date(), res);
            } else {
                return JsonResult.custom(202, "The server encountered an internal error", new Date(), "");
            }
        } else if ("2".equals(stype)) { //老师
            //得到数据
            Map res = GetAllByMC(lymc);
            if (!res.isEmpty()) {
                //查询当天的人流量
                List<Map<String, Object>> listmap = crxxlsDao.GetByNaDa(NameConvert.getrrightname(lymc), TimeUtils.getinitday(), TimeUtils.getformattime());
                //查询指定时间段，指定大门的单位人流量
                List<Map<String, Object>> listmap1 = crxxlsDao.GetByNaDa(NameConvert.getrrightname(lymc), stime, etime);
                //创建接受集合和返回集合
                List<String> date = new ArrayList<>();
                List<Integer> value = new ArrayList<>();
                //创建一个用于计算当天人流量的集合
                List<Integer> values = new ArrayList<>();
                //使用循环接受数据
                if (!listmap.isEmpty()) {
                    for (Map map : listmap) {
                        values.add(Integer.parseInt(map.get("HOUR_JNUM").toString()));
                    }
                    //今天小时最大人流量
                    res.put("rll_max", Collections.max(values));
                    //今天的人流量
                    res.put("rll_all", values.stream().reduce(Integer::sum).orElse(0));
                } else {
                    //今天小时最大人流量
                    res.put("rll_max", 0);
                    //今天的人流量
                    res.put("rll_all", 0);
                }
                //使用循环查询数据
                for (Map map : listmap1) {
                    date.add(map.get("HOUR").toString());
                    value.add(Integer.parseInt(map.get("HOUR_JNUM").toString()));
                }
                //时间坐标
                res.put("date", date);
                //小时人流量
                res.put("value", value);
                //当前小时人流量
                res.put("rll", GetHourRndByDaLs(lymc));
                //楼宇容纳度
                res.put("rnd", "0.00");
                //返回数据
                return JsonResult.custom(200, "", new Date(), res);

            } else {
                return JsonResult.custom(202, "The server encountered an internal error", new Date(), "");
            }

        } else if ("0".equals(stype)) { //混合人员（老师，学生）
            //得到数据
            Map res = GetAllByMC(lymc);
            if (!res.isEmpty()) {
                //查询当天的人流量
                List<Map<String, Object>> listmap1 = crxxDao.GetByNaDa(NameConvert.getrrightname(lymc), TimeUtils.getinitday(), TimeUtils.getformattime());
                List<Map<String, Object>> listmap2 = crxxlsDao.GetByNaDa(NameConvert.getrrightname(lymc), TimeUtils.getinitday(), TimeUtils.getformattime());
                //查询指定时间段，指定大门的单位人流量
                List<Map<String, Object>> listmap3 = crxxDao.GetByNaDa(NameConvert.getrrightname(lymc), stime, etime);
                List<Map<String, Object>> listmap4 = crxxlsDao.GetByNaDa(NameConvert.getrrightname(lymc), stime, etime);
                //接受返回的数据
                LinkedHashMap<String, Object> map1 = MixInfo.mixtwoinfo(listmap1, listmap2);
                LinkedHashMap<String, Object> map2 = MixInfo.mixtwoinfo(listmap3, listmap4);
                //创建一个值集合，用来收集当日所有的人流量值
                List<Integer> values = new ArrayList<>();
                //处理map1集合
                Set<Map.Entry<String, Object>> set1 = map1.entrySet();
                Iterator<Map.Entry<String, Object>> iterator1 = set1.iterator();
                while (iterator1.hasNext()) {
                    Map.Entry entry = iterator1.next();
                    Integer num = (Integer) entry.getValue();
                    values.add(num);
                }
                //处理当日的人流量值
                if (!values.isEmpty()) {
                    //今天小时最大人流量
                    res.put("rll_max", Collections.max(values));
                    //今天的人流量
                    res.put("rll_all", values.stream().reduce(Integer::sum).orElse(0));
                } else {
                    //今天小时最大人流量
                    res.put("rll_max", 0);
                    //今天的人流量
                    res.put("rll_all", 0);
                }
                //创建接受集合和返回集合
                List<String> date = new ArrayList<>();
                List<Integer> value = new ArrayList<>();
                //使用循环查询特定时间段的map2数据
                Set<Map.Entry<String, Object>> set2 = map2.entrySet();
                Iterator<Map.Entry<String, Object>> iterator2 = set2.iterator();
                while (iterator2.hasNext()) {
                    Map.Entry entry = iterator2.next();
                    String time = (String) entry.getKey();
                    Integer num = (Integer) entry.getValue();
                    date.add(time);
                    value.add(num);
                }
                //时间坐标
                res.put("date", date);
                //小时人流量
                res.put("value", value);
                //当前小时人流量
                res.put("rll", GetHourRndByDaLs(lymc) + GetHourRndByDa(lymc));
                //楼宇容纳度
                res.put("rnd", "0.00");
                //返回数据
                return JsonResult.custom(200, "", new Date(), res);
            } else {
                return JsonResult.custom(202, "The server encountered an internal error", new Date(), "");
            }
        }
        return JsonResult.custom(202, "The server encountered an internal error", new Date(), "");
    }

    @Override
    public JsonResult GetAllMcBh() {
        // 得到数据
        List<Map<String,Object>> listmap = lyDao.findAllInfo();
        //判断查询到的数据是否为空
        if(!listmap.isEmpty()){
            //创建返回集合
            Map<String,Object> res = new HashMap<>();
            //循环list集合取出数据
            for (Map map:listmap){
                res.put(map.get("LYMC").toString(),Integer.parseInt(map.get("LYBH").toString()));
            }
            //返回数据
            return JsonResult.custom(200,"",new Date(),res);
        }else {
            //返回数据
            return JsonResult.custom(202,"The server encountered an internal error",new Date(),"");
        }
    }

    @Override
    public Map<String, HashMap> GetAllByMC(String LYMC) {
        //得到数据
        LY ly = lyDao.findInfoByMc(LYMC);
        //创建返回集合
        Map res = new HashMap();
        if (ly != null){
            //设置楼宇名称
            res.put("csname",ly.getLYMC());
            //设置经纬度
            List<Double> lnglat=new ArrayList<>();
            lnglat.add(Double.parseDouble(ly.getLYJD()));
            lnglat.add(Double.parseDouble(ly.getLYWD()));
            res.put("lngLat",lnglat);
            //返回数据
            return res;
        }else {
            return res;
        }
    }
}
